/*
 * 同步阻塞客户端
 * 功能：填入外部地址，对方host开启date time服务，拉取对方的时间
 */
#include <iostream>
#include <boost/array.hpp>
#include <boost/asio.hpp>

using boost::asio::ip::tcp;
//客户端使用tcp服务，socket使用tcp
int main(int argc, char *argv[]) {
	try {
		if(argc != 2) {
			std::cerr << "Usage: client <host>" << std::endl;
			return 1;
		}

		boost::asio::io_service io_service;
		//程序与操作系统的桥梁，在linux下调用epoll，在win下面调用iocp
		tcp::resolver resolver(io_service);
		//用来解析，调用系统函数query地址是什么，找到ip和port
		tcp::resolver::query query(argv[1], "daytime");
		//可以传入一个ip地址，或者网址通过DNS解析，第二个参数可以传入端口号
		//或者服务代码，程序如何知道服务的端口号：
		//linux ip:/etc/hosts | dns解析 port:/etc/services
		//如果是不存在的服务，抛出异常
		tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
		//query可能有若干个地址，返回一个可以用的
		tcp::socket socket(io_service);
		boost::asio::connect(socket, endpoint_iterator);
		//同步、阻塞，如果无法连接将抛出异常,所以使用try catch
		//去链接endpoint
		for(;;) {
			boost::array<char, 128> buf;
			boost::system::error_code error;
			//所有asio的接口都有两种形式，抛出异常/error_code&
			//daytime服务 由服务器断开客户端的，所以这样判断
			size_t len = socket.read_some(boost::asio::buffer(buf), error);
			//read_size < buf_size 读入部分字节/还没读完/对方已经传入完毕
			//字节流服务，客户端可以用，服务器不太行
			//不清楚对方传入多少字节，或者下载一个东西可以用read_some
			//一般是用异步非阻塞
			if(error == boost::asio::error::eof)
				break;//connection closed cleanly by peer
			else if(error)
				throw boost::system::system_error(error); //some other error
			std::cout.write(buf.data(), len);
			//有什么直接输出，以const char*的样子
			//std::cout << buf.data();
			//会格式转换什么的
		}
	}	
	catch (std::exception &e) {
		std::cerr << e.what() << std::endl;
	}
	return 0;
}
